package com.ds.springboot.controller;

import com.alibaba.fastjson.JSON;
import com.ds.springboot.entity.PayloadDTO;
import com.ds.springboot.entity.User;
import com.ds.springboot.exception.JwtSignatureVerifyException;
import com.ds.springboot.service.UserService;
import com.ds.springboot.util.JwtUtil;
import com.nimbusds.jose.JOSEException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @program: springboot-1-cache
 * @description:
 * @author: Dawson.Zhang
 * @create: 2020-05-26
 **/
@Slf4j
@RestController
public class UserController {
    @Autowired
    UserService userService;

    @Value("${my.jwt.signature.algorithm.secret}")
    private String signatureAlgorithmSecret;

    @Value("${my.jwt.expiration.time}")
    private long tokenExpirationTime;

    /**
     * 用户登录, 并返回token信息
     *
     * 注:真正使用时，往往除了token，还会返回一些其他的相关信息。
     * 注:真正使用时，token往往放在响应头里面进行返回。
     * 注:真正使用时，用户登录不应用get方法，而是用post方法。
     *
     * @param name 用户名
     * @param password mima
     *
     * @return  返回jwt
     * @date 2019/7/21 11:05
     */
    @GetMapping("/login")
    public String login(@RequestParam("name") String name,
                        @RequestParam("password")  String password){
        // 模拟 用户名密码 均正确
        User user = userService.login(name, password);
        if(user != null) {
            /*
             * 模拟获得有效负载信息
             * 注:根据自己业务的不同，往往这一步会有非常大的不同
             */
            String s = JSON.toJSONString(user);
            PayloadDTO payloadDTO  = getPayload(s);
            // 生成token
            String payloadJsonString = JSON.toJSONString(payloadDTO);
            String token;
            try {
                token = JwtUtil.generateToken(payloadJsonString, signatureAlgorithmSecret);
            } catch (JOSEException e) {
                log.error("生成token失败！", e);
                return "生成token失败";
            }
            return token;
        }
        return "用户名密码有误！";
    }

    /**
     * 验证请求中的token是否被篡改、是否过期(是否有效)。
     * 如果有效那么返回响应的业务信息。
     *
     * 注:真正使用时，token的验证往往在Filter或AOP中进行。
     * 注:真正使用时，一般将token放在请求头中，以Authorization作为key，以Bearer <token>作为值。
     *
     * @param token json web token（JWT）
     *
     * @return  返回相应信息
     * @date 2019/7/21 11:05
     */
    @GetMapping("/test")
    public String logis(){
       return  "访问成功";
    }

    /**
     * 模拟生成 有效负载信息
     *
     * 注:根据自己业务情况的不同，可能会往有效负载中放入不同的信息；
     *    此步骤的逻辑也可能会非常复杂。
     *
     * @date 2019/7/21 16:00
     */
    private PayloadDTO getPayload(String user) {
        PayloadDTO build = PayloadDTO.builder()
            // 放置过期时长
            .exp(tokenExpirationTime)
            // 放置生效时间
            .nbf(LocalDateTime.now())
            // 放置用户信息
            .user(user)
            .isAdmin(true)
            .build();
        return build;
    }


}
